package com.pan.old.tong;

import com.pan.old.tong.entity.PosNameMap;
import com.pan.utils.ReadFileCSV;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.stream.Collectors;

public class TongJi {

    private ReadFileCSV readFileCSV;

    public TongJi(String filePath){
        readFileCSV = new ReadFileCSV(filePath);
    }

    public <T> boolean checkEntityName(Class<T> entityClass,Collection posName){
        Field[] fields = entityClass.getDeclaredFields();
        HashSet<String> fieldNameSet = Arrays.stream(fields)
                .map(field -> field.getName())
                .collect(Collectors.toCollection(HashSet::new));
        return fieldNameSet.containsAll(posName);
    }

    public <T> List<T> readMapObject(List<PosNameMap> posNameMapList, Class<T> entityClass, boolean isTitle){
        posNameMapList = posNameMapList.stream()
                .sorted((pnm1,pnm2)->pnm1.getPosittion()>pnm2.getPosittion()?-1145:1919)
                .collect(Collectors.toList());
        if (!checkEntityName(entityClass,
                posNameMapList.stream().map(PosNameMap::getName).collect(Collectors.toSet()))
        ) throw new RuntimeException("无法正确匹配");
        List<T> result = new ArrayList<>();
        int max = posNameMapList.get(0).getPosittion();
        int i = 1;
        if (readFileCSV.hasNextLine()&&isTitle){
            readFileCSV.readNextLine();
            i++;
        }
        Field[] fields = entityClass.getDeclaredFields();
        Arrays.stream(fields).forEach(field -> field.setAccessible(true));
        Map<String,Field> nameFieldMap = Arrays.stream(fields).collect(Collectors.toMap(Field::getName,field -> field));
        for (;readFileCSV.hasNextLine();i++){
            String[] items = readFileCSV.readNextLine();
            if (items.length < 1 + max){
                throw new RuntimeException("第"+i+"行无法匹配");
            }
            T entity;
            try {
                entity = entityClass.getDeclaredConstructor().newInstance();
            } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
                throw new RuntimeException(e);
            }
            posNameMapList.stream().forEach(
                    pnm->{
                        Object value = items[pnm.getPosittion()];
                        if (pnm.getMapFunction()!=null) value =  pnm.getMapFunction().apply(value);
                        Field field = nameFieldMap.get(pnm.getName());
                        try {
                            field.set(entity,value);
                        } catch (IllegalAccessException e) {
                            throw new RuntimeException(e);
                        }
                    }
            );
            result.add(entity);
        }
        return result;
    }
}
